package model.population;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Random;


import model.factory.SimpleStringOrganismFactory;
import model.organism.Organism;
import model.organism.SimpleStringOrganism;

public class StaticSizePopulation implements Population{
	
	private static int populationSize = 100;
	private ArrayList<Organism> population = new ArrayList<Organism>(populationSize);
	Random randomNumberGenerator = new Random(System.currentTimeMillis());
	
	public StaticSizePopulation()
	{
		for(int i = 0; i < populationSize; i++)
		{
			population.add(new SimpleStringOrganism());
		}
	}
	
	public int getPopulationSize()
	{
		return populationSize;
	}

	public ArrayList<Organism> getPopulation() {
		return population;
	}

	public Organism getOrganismAtIndex(int index) 
	{
		if(population == null)
		{
			return null;
		}
		if(index >= populationSize || index < 0)
		{
			return null;
		}
		return population.get(index);
	}
	
	public void setOrganismAtIndex(int index, Organism organism) 
	{
		if(index < populationSize && index >= 0)
		{
			population.set(index, organism);
		}
	}

	@Override
	public Organism getRandomOrganism()
	{
		return getOrganismAtIndex(randomNumberGenerator.nextInt());
	}

	@Override
	public void populateRandomly()
	{
		population.clear();
		for(int i = 0; i < populationSize; i++)
		{
			SimpleStringOrganism organism = SimpleStringOrganismFactory.createRandomOrganism();
			population.add(organism);
		}
	}

	@Override
	public Collection<Organism> getBestOrganisms()
	{
		Collection<Organism> bestOrganisms = new ArrayList<Organism>();
		float bestFitness = 0.0f;
		for(int i = 0; i < population.size(); i++)
		{
			float currentOrganismFitness = population.get(i).calculateFitness();
			if(currentOrganismFitness == bestFitness)
			{
				bestOrganisms.add(population.get(i));
			}
			else if(currentOrganismFitness > bestFitness)
			{
				bestOrganisms.clear();
				bestOrganisms.add(population.get(i));
				bestFitness = currentOrganismFitness;
			}
		}
		return bestOrganisms;
	}
	
	@Override
	public Collection<Organism> getWorstOrganisms()
	{
		Collection<Organism> worstOrganisms = new ArrayList<Organism>();
		float worstFitness = 1.0f;
		for(int i = 0; i < population.size(); i++)
		{
			float currentOrganismFitness = population.get(i).calculateFitness();
			if(currentOrganismFitness == worstFitness)
			{
				worstOrganisms.add(population.get(i));
			}
			else if(currentOrganismFitness < worstFitness)
			{
				worstOrganisms.clear();
				worstOrganisms.add(population.get(i));
				worstFitness = currentOrganismFitness;
			}
		}
		return worstOrganisms;
	}

}
